package net.pimpas.transformation.xml.xstream.serviceprovider;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Reader;
import java.io.Writer;

import net.pimpas.core.configuration.exception.ConfigurationException;
import net.pimpas.core.serviceprovider.ServiceProviderAnnotation;
import net.pimpas.core.serviceprovider.instancetype.ServiceProviderInstanceType;
import net.pimpas.transformation.serviceprovider.exception.TransformationServiceProviderException;
import net.pimpas.transformation.xml.serviceprovider.XmlTransformationServiceProvider;
import net.pimpas.transformation.xml.xstream.serviceprovider.annotation.Annotations;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
import com.thoughtworks.xstream.io.xml.DomDriver;

@ServiceProviderAnnotation(
		instanceType=ServiceProviderInstanceType.NORMAL, 
		serviceProviderType=XmlTransformationServiceProvider.class
)
public class XStreamTransformationServiceProviderImpl implements XStreamTransformationServiceProvider {
	
	private XStream xstream;
	
	public XStreamTransformationServiceProviderImpl() {
		this.setXstream(new XStream(new DomDriver()));
	}
	
	public XStreamTransformationServiceProviderImpl(HierarchicalStreamDriver o) {
		this.setXstream(new XStream(o));
	}
	
	public XStreamTransformationServiceProviderImpl(ReflectionProvider o) {
		this.setXstream(new XStream(o));
	}
	
	public String to(Object arg0, Object... parameters) throws TransformationServiceProviderException {
		// configure annotations
		Annotations.configureAliases(this.getXstream(), arg0.getClass());
		try {
			return this.getXstream().toXML(arg0);
		} catch(Exception e) {
			throw new TransformationServiceProviderException(e);
		}
	}

	public void config() throws ConfigurationException {
		
	}

	public ObjectInputStream createObjectInputStream(Reader arg0) throws TransformationServiceProviderException {
		try {
			return this.getXstream().createObjectInputStream(arg0);
		} catch (IOException e) {
			throw new TransformationServiceProviderException(e);
		}
	}

	public ObjectOutputStream createObjectOutputStream(Writer arg0) throws TransformationServiceProviderException {
		try {
			return this.getXstream().createObjectOutputStream(arg0);
		} catch (IOException e) {
			throw new TransformationServiceProviderException(e);
		}
	}

	public XStream getXstream() {
		return xstream;
	}

	public void setXstream(XStream xstream) {
		this.xstream = xstream;
	}

	public Object from(String arg0, Object... parameters) throws TransformationServiceProviderException {
		return this.getXstream().fromXML(arg0);
	}
	
	public boolean isTerminated() {
		return false;
	}
}